﻿using ChikovMF.Application.Common.Exceptions;
using ChikovMF.Application.Common.Interfaces;
using ChikovMF.Application.Features.Files.Shared;
using ChikovMF.Application.Features.Images.Processing;
using ChikovMF.Entities;
using MediatR;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;

namespace ChikovMF.Application.Features.Projects.UploadImagesCommand;

public class UploadImagesCommandHandler : IRequestHandler<UploadImagesCommand>
{
    public async Task Handle(UploadImagesCommand request, CancellationToken cancellationToken)
    {
        var project = await _context.Projects
            .Include(p => p.CardImage)
            .Include(p => p.SliderImages)
            .FirstOrDefaultAsync(p => p.ProjectId == request.ProjectId, cancellationToken);

        if (project == null)
        {
            throw new NotFoundEntityException(nameof(Project), request.ProjectId);
        }

        if (project.CardImage != null)
        {
            await _fileManager.DeleteFile(project.CardImage.PathLocation, project.CardImage.Name, cancellationToken);
        }
        project.CardImage = null;
        if (project.SliderImages != null)
        {
            foreach (var oldImage in project.SliderImages)
            {
                await _fileManager.DeleteFile(oldImage.PathLocation, oldImage.Name, cancellationToken);
            }
        }
        project.SliderImages = new List<SliderImage>();

        if (request.CardImage != null)
        {
            var resizeOptions = new ResizeOptions
            {
                Mode = ResizeMode.Crop,
                Size = new Size(640, 426)
            };

            var imageDto = await ProcessAndSaveImage(request.CardImage, resizeOptions, cancellationToken);

            if (imageDto != null)
            {
                project.CardImage = new CardImage
                {
                    Name = imageDto.Name,
                    PathLocation = imageDto.PathLocation,
                    Alt = $"Изображение карточки проекта: {project.Name}",
                    Url = imageDto.Url,
                    UploadDate = DateTime.UtcNow,
                };
            }
        }

        if (request.SliderImages != null)
        {
            foreach (var image in request.SliderImages)
            {
                if (image == null)
                {
                    continue;
                }

                var resizeOptions = new ResizeOptions
                {
                    Mode = ResizeMode.Crop,
                    Size = new Size(1920, 1080)
                };
                var imageDto = await ProcessAndSaveImage(image, resizeOptions, cancellationToken);

                if (imageDto != null)
                {
                    project.SliderImages.Add(new SliderImage
                    {
                        Name = imageDto.Name,
                        PathLocation = imageDto.PathLocation,
                        Alt = $"Изображение слайдера проекта: {project.Name} №{project.SliderImages.Count + 1}",
                        Url = imageDto.Url,
                        UploadDate = DateTime.UtcNow,
                    });
                }
            }
        }

        await _context.SaveChangesAsync(cancellationToken);
    }

    private async Task<FileDto> ProcessAndSaveImage(IFormFile formFile, ResizeOptions resizeOptions, CancellationToken cancellationToken)
    {
        FileDto fileDto;

        var imageProcessingCommand = new ImageProcessingCommand
        {
            Stream = formFile.OpenReadStream(),
            ResizeOptions = resizeOptions
        }; 

        using (var imageStream = await _mediator.Send(imageProcessingCommand, cancellationToken))
        {
            fileDto = await _fileManager.SaveFile(imageStream, "Images", formFile.FileName, cancellationToken);
        }

        return fileDto;
    }

    private readonly IChikovMFContext _context;
    private readonly IMediator _mediator;
    private readonly IFileManager _fileManager;

    public UploadImagesCommandHandler(IChikovMFContext context, IMediator mediator, IFileManager fileManager)
    {
        _context = context;
        _mediator = mediator;
        _fileManager = fileManager;
    }
}
